<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="zh-CN">
<head>
    <title>智障AI - 人工智能助手</title>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="description" content="智障AI - 一个有趣的人工智能助手"/>
    <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🤪</text></svg>">
    <style type="text/css">
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        #chat-container {
            height: 400px;
            border: 1px solid #ddd;
            border-radius: 8px;
            overflow-y: auto;
            padding: 10px;
            margin-bottom: 20px;
            background-color: white;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .message {
            margin-bottom: 10px;
            padding: 10px;
            border-radius: 8px;
            max-width: 80%;
            word-wrap: break-word;
            white-space: pre-wrap;
            line-height: 1.5;
            font-size: 16px;
        }
        .user-message {
            background-color: #e3f2fd;
            margin-left: 20%;
            align-self: flex-end;
        }
        .ai-message {
            background-color: #f5f5f5;
            margin-right: 20%;
            position: relative;
            padding-left: 15px;
            border-left: 3px solid #2196f3;
        }
        .ai-message.typing::after {
            content: '';
            display: inline-block;
            width: 4px;
            height: 4px;
            background-color: #666;
            border-radius: 50%;
            margin-left: 4px;
            animation: typing 1s infinite;
        }
        @keyframes typing {
            0%, 100% { opacity: 0.2; }
            50% { opacity: 1; }
        }
        .system-message {
            background-color: #ffebee;
            color: #c62828;
            margin: 10px auto;
            text-align: center;
            max-width: 100%;
            font-weight: 500;
        }
        code {
            background-color: #f8f9fa;
            padding: 2px 4px;
            border-radius: 4px;
            font-family: monospace;
            font-size: 14px;
            color: #e91e63;
        }
        pre {
            background-color: #f8f9fa;
            padding: 10px;
            border-radius: 4px;
            overflow-x: auto;
            margin: 10px 0;
            border: 1px solid #e0e0e0;
        }
        pre code {
            background-color: transparent;
            padding: 0;
            color: #333;
        }
        blockquote {
            margin: 10px 0;
            padding-left: 15px;
            border-left: 3px solid #9e9e9e;
            color: #666;
        }
        p {
            margin: 8px 0;
        }
        ul, ol {
            margin: 8px 0;
            padding-left: 20px;
        }
        table {
            border-collapse: collapse;
            width: 100%;
            margin: 10px 0;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f5f5f5;
        }
        img {
            max-width: 100%;
            height: auto;
            border-radius: 4px;
            margin: 10px 0;
        }
        #input-container {
            display: flex;
            gap: 10px;
            position: relative;
        }
        #message-input {
            flex-grow: 1;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
        }
        #message-input:disabled {
            background-color: #f5f5f5;
        }
        button {
            padding: 12px 24px;
            background-color: #2196f3;
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #1976d2;
        }
        button:disabled {
            background-color: #bdbdbd;
            cursor: not-allowed;
        }
        .loading {
            position: absolute;
            right: 120px;
            top: 50%;
            transform: translateY(-50%);
            color: #666;
        }
        #status-message {
            text-align: center;
            color: #666;
            margin-top: 10px;
            font-size: 14px;
            min-height: 20px;
        }
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
            z-index: 1000;
        }
        .modal-content {
            position: relative;
            background-color: white;
            margin: 15% auto;
            padding: 20px;
            border-radius: 8px;
            width: 80%;
            max-width: 400px;
            text-align: center;
        }
        .modal-buttons {
            margin-top: 20px;
        }
        .modal-buttons button {
            margin: 0 10px;
            padding: 8px 16px;
        }
        .modal-buttons .secondary {
            background-color: #9e9e9e;
        }
        .header {
            position: relative;
            text-align: center;
            margin-bottom: 20px;
            padding: 20px;
        }
        .brand {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 10px;
        }
        .brand-icon {
            font-size: 24px;
        }
        .brand h1 {
            font-size: 24px;
            color: #333;
            margin: 0;
            font-weight: 500;
        }
        .header p {
            font-size: 14px;
            color: #666;
            margin: 5px 0 0 0;
        }
        .user-info {
            position: absolute;
            top: 20px;
            right: 20px;
            display: flex;
            align-items: center;
            gap: 15px;
            padding: 8px;
            border-radius: 20px;
            z-index: 100;
        }
        .user-avatar {
            cursor: pointer;
            font-size: 20px;
            width: 36px;
            height: 36px;
            background-color: #2196f3;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            transition: transform 0.2s;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        .user-avatar:hover {
            transform: scale(1.05);
        }
        .user-dropdown {
            position: relative;
        }
        .dropdown-menu {
            display: none;
            position: absolute;
            right: 0;
            top: 120%;
            background-color: white;
            min-width: 220px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            border-radius: 8px;
            padding: 12px;
            z-index: 1000;
        }
        .dropdown-menu.show {
            display: block;
            animation: fadeIn 0.2s ease-out;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        .dropdown-divider {
            height: 1px;
            background-color: #eee;
            margin: 8px 0;
        }
        .user-details {
            padding: 8px 0;
            display: flex;
            flex-direction: column;
            gap: 4px;
        }
        .user-nickname {
            font-size: 16px;
            font-weight: 500;
            color: #2196f3;
        }
        .user-username, .user-email {
            font-size: 14px;
            color: #666;
        }
        .login-prompt {
            display: flex;
            align-items: center;
            gap: 8px;
            background-color: #f8f9fa;
            padding: 6px 12px;
            border-radius: 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }
        .login-link {
            color: #2196f3;
            text-decoration: none;
            font-weight: 500;
            font-size: 14px;
            padding: 4px 8px;
            border-radius: 4px;
            transition: background-color 0.2s;
        }
        .login-link:hover {
            background-color: #e3f2fd;
        }
        .login-separator {
            color: #666;
            font-size: 14px;
        }
        .logout-btn {
            width: 100%;
            color: #dc3545;
            text-decoration: none;
            font-size: 14px;
            padding: 8px;
            border-radius: 4px;
            transition: all 0.3s;
            border: none;
            background: none;
            cursor: pointer;
            text-align: left;
        }
        .logout-btn:hover {
            background-color: #dc3545;
            color: white;
        }
    </style>
</head>
<body>
    <div class="header">
        <div class="user-info">
            <div th:if="${nickname != null}" class="user-dropdown">
                <div class="user-avatar" th:text="${#strings.substring(nickname,0,1)}" onclick="toggleDropdown()">头</div>
                <div class="dropdown-menu">
                    <div class="user-details">
                        <span class="user-nickname" th:text="${nickname}">昵称</span>
                        <span class="user-username" th:if="${#authentication != null}" th:text="${#authentication.name}">用户名</span>
                        <span class="user-email" th:if="${email != null}" th:text="${email}">邮箱</span>
                    </div>
                    <div class="dropdown-divider"></div>
                    <form th:action="@{/logout}" method="post" style="margin: 0;">
                        <button type="submit" class="logout-btn">退出登录</button>
                    </form>
                </div>
            </div>
            <div th:unless="${nickname != null}" class="login-prompt">
                <a href="/login" class="login-link">登录</a>
                <span class="login-separator">或</span>
                <a href="/register" class="login-link">注册</a>
            </div>
        </div>
        <div class="brand">
            <span class="brand-icon">🤪</span>
            <h1>智障AI</h1>
        </div>
        <p>一个有点憨但很真诚的AI助手</p>
    </div>
    <div id="chat-container"></div>
    <div id="input-container">
        <input type="text" id="message-input" placeholder="输入消息..." autocomplete="off"/>
        <div id="loading" class="loading" style="display: none;">处理中...</div>
        <button onclick="sendMessage()" id="send-button" type="button">发送</button>
    </div>
    <div id="status-message"></div>

    <div id="loginModal" class="modal">
        <div class="modal-content">
            <h2>登录提示</h2>
            <p>登录后即可与智障AI开始对话</p>
            <div class="modal-buttons">
                <button onclick="window.location.href='/login'" class="btn btn-primary" style="background-color: #2196f3;">去登录</button>
                <button onclick="window.location.href='/register'" class="btn btn-secondary" style="background-color: #9e9e9e;">去注册</button>
                <button onclick="closeLoginModal()" class="btn btn-cancel" style="background-color: #f5f5f5; color: #666;">取消</button>
            </div>
        </div>
    </div>

    <script th:inline="javascript">
        /*<![CDATA[*/
        const chatContainer = document.getElementById('chat-container');
        const messageInput = document.getElementById('message-input');
        const sendButton = document.getElementById('send-button');
        const loadingIndicator = document.getElementById('loading');
        const statusMessage = document.getElementById('status-message');
        const loginModal = document.getElementById('loginModal');
        const isAuthenticated = [[${nickname != null}]];

        let isWaiting = false;
        const THROTTLE_DELAY = 1000;
        let lastMessageTime = 0;
        let messageCount = 0;
        const MESSAGE_LIMIT = 10;

        const style = document.createElement('style');
        style.textContent = `
            .modal {
                display: none;
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-color: rgba(0,0,0,0.5);
                z-index: 1000;
            }
            .modal-content {
                position: relative;
                background-color: white;
                margin: 15% auto;
                padding: 20px;
                border-radius: 8px;
                width: 80%;
                max-width: 400px;
                text-align: center;
            }
            .modal-buttons {
                margin-top: 20px;
            }
            .modal-buttons button {
                margin: 0 10px;
                padding: 8px 16px;
            }
            .modal-buttons .secondary {
                background-color: #9e9e9e;
            }
        `;
        document.head.appendChild(style);

        const modal = document.createElement('div');
        modal.className = 'modal';
        modal.innerHTML = `
            <div class="modal-content">
                <h2>提示</h2>
                <p>您已达到免费使用次数上限，要不要给这个智障充点钱？</p>
                <div class="modal-buttons">
                    <button onclick="handleRecharge()">给智障充钱</button>
                    <button class="secondary" onclick="closeModal()">我考虑考虑</button>
                </div>
            </div>
        `;
        document.body.appendChild(modal);

        function showRechargeModal() {
            modal.style.display = 'block';
        }

        function closeModal() {
            modal.style.display = 'none';
        }

        function handleRecharge() {
            alert('智障还在学习如何收钱，请联系管理员~');
            closeModal();
        }

        function showLoginModal() {
            loginModal.style.display = 'block';
        }

        function closeLoginModal() {
            loginModal.style.display = 'none';
        }

        function addMessage(message, type) {
            const messageDiv = document.createElement('div');
            if (message.startsWith('系统提示：')) {
                messageDiv.className = 'message system-message';
            } else {
                messageDiv.className = `message ${type}-message`;
                if (type === 'user') {
                    messageCount++;
                    if (messageCount === MESSAGE_LIMIT) {
                        showRechargeModal();
                    }
                } else if (type === 'ai') {
                    messageDiv.classList.add('typing');
                }
            }
            
            // 处理Markdown样式的文本
            let formattedMessage = message;
            
            // 处理代码块
            formattedMessage = formattedMessage.replace(/```(\w*)\n([\s\S]*?)```/g, function(match, lang, code) {
                return `<pre><code class="language-${lang}">${code.trim()}</code></pre>`;
            });
            
            // 处理行内代码
            formattedMessage = formattedMessage.replace(/`([^`]+)`/g, '<code>$1</code>');
            
            // 处理引用
            formattedMessage = formattedMessage.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');
            
            // 处理列表
            formattedMessage = formattedMessage.replace(/^- (.+)$/gm, '<li>$1</li>');
            formattedMessage = formattedMessage.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
            
            // 处理数字列表
            formattedMessage = formattedMessage.replace(/^\d+\. (.+)$/gm, '<li>$1</li>');
            formattedMessage = formattedMessage.replace(/(<li>.*<\/li>)/s, '<ol>$1</ol>');
            
            // 处理加粗
            formattedMessage = formattedMessage.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
            
            // 处理斜体
            formattedMessage = formattedMessage.replace(/\*(.+?)\*/g, '<em>$1</em>');
            
            // 处理换行
            formattedMessage = formattedMessage.replace(/\n/g, '<br>');
            
            messageDiv.innerHTML = formattedMessage;
            chatContainer.appendChild(messageDiv);
            chatContainer.scrollTop = chatContainer.scrollHeight;
            
            // 如果是AI消息，在完成时移除typing效果
            if (type === 'ai') {
                setTimeout(() => {
                    messageDiv.classList.remove('typing');
                }, 500);
            }
        }

        function setLoading(loading) {
            messageInput.disabled = loading;
            sendButton.disabled = loading || messageCount >= MESSAGE_LIMIT;
            loadingIndicator.style.display = loading ? 'block' : 'none';
            if (!loading) {
                messageInput.focus();
            }
        }

        function updateStatus(message, isError = false) {
            statusMessage.textContent = message;
            statusMessage.style.color = isError ? '#c62828' : '#666';
            if (message && !isError) {
                setTimeout(() => {
                    statusMessage.textContent = '';
                }, 2000);
            }
        }

        async function sendMessage() {
            const message = messageInput.value.trim();
            if (!message) return;

            if (!isAuthenticated) {
                showLoginModal();
                return;
            }

            if (messageCount >= MESSAGE_LIMIT) {
                showRechargeModal();
                return;
            }

            const now = Date.now();
            if (isWaiting || (now - lastMessageTime < THROTTLE_DELAY)) {
                updateStatus('请稍等片刻再发送消息', true);
                return;
            }

            setLoading(true);
            isWaiting = true;
            lastMessageTime = now;
            
            addMessage(message, 'user');
            messageInput.value = '';

            let currentMessageDiv = null;
            let currentContent = '';

            try {
                const response = await fetch('/api/chat/stream', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'Accept': 'text/event-stream',
                    },
                    body: `message=${encodeURIComponent(message)}`
                });

                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }

                const reader = response.body.getReader();
                const decoder = new TextDecoder();

                while (true) {
                    const {value, done} = await reader.read();
                    if (done) {
                        setLoading(false);
                        isWaiting = false;
                        if (currentMessageDiv) {
                            currentMessageDiv.classList.remove('typing');
                        }
                        break;
                    }

                    const chunk = decoder.decode(value, {stream: true});
                    const lines = chunk.split('\n');

                    for (const line of lines) {
                        if (!line.trim() || !line.startsWith('data: ')) continue;

                        const data = line.slice(5).trim();
                        if (data === '[DONE]') {
                            setLoading(false);
                            isWaiting = false;
                            if (currentMessageDiv) {
                                currentMessageDiv.classList.remove('typing');
                            }
                            continue;
                        }

                        try {
                            const jsonData = JSON.parse(data);
                            
                            if (jsonData.code === 500) {
                                addMessage('系统提示：' + jsonData.msg, 'system');
                                updateStatus(jsonData.msg, true);
                                break;
                            }

                            if (jsonData.code === 200 && jsonData.choices && jsonData.choices.length > 0) {
                                const choice = jsonData.choices[0];
                                const content = choice.delta?.content || '';
                                
                                if (content || choice.finish_reason === 'stop') {
                                    if (!currentMessageDiv) {
                                        currentMessageDiv = document.createElement('div');
                                        currentMessageDiv.className = 'message ai-message typing';
                                        chatContainer.appendChild(currentMessageDiv);
                                    }

                                    if (content.startsWith('系统提示：')) {
                                        currentMessageDiv.className = 'message system-message';
                                        updateStatus(content, true);
                                    }

                                    if (content) {
                                        currentContent += content;
                                        currentMessageDiv.innerHTML = formatMessage(currentContent);
                                        chatContainer.scrollTop = chatContainer.scrollHeight;
                                    }
                                }
                            }
                        } catch (e) {
                            console.error('Error parsing JSON:', e, data);
                            if (!currentMessageDiv) {
                                addMessage('系统提示：解析响应失败', 'system');
                                updateStatus('解析响应失败', true);
                            }
                        }
                    }
                }
            } catch (error) {
                console.error('Error:', error);
                addMessage('系统提示：发送消息失败，请重试', 'system');
                updateStatus('发送消息失败，请重试', true);
            } finally {
                setLoading(false);
                isWaiting = false;
            }
        }

        function formatMessage(message) {
            let formatted = message;
            
            // 处理代码块
            formatted = formatted.replace(/```(\w*)\n([\s\S]*?)```/g, function(match, lang, code) {
                return `<pre><code class="language-${lang}">${code.trim()}</code></pre>`;
            });
            
            // 处理行内代码
            formatted = formatted.replace(/`([^`]+)`/g, '<code>$1</code>');
            
            // 处理引用
            formatted = formatted.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');
            
            // 处理列表
            formatted = formatted.replace(/^- (.+)$/gm, '<li>$1</li>');
            formatted = formatted.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
            
            // 处理数字列表
            formatted = formatted.replace(/^\d+\. (.+)$/gm, '<li>$1</li>');
            formatted = formatted.replace(/(<li>.*<\/li>)/s, '<ol>$1</ol>');
            
            // 处理加粗
            formatted = formatted.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
            
            // 处理斜体
            formatted = formatted.replace(/\*(.+?)\*/g, '<em>$1</em>');
            
            // 处理换行
            formatted = formatted.replace(/\n/g, '<br>');
            
            return formatted;
        }

        messageInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                if (!isAuthenticated) {
                    showLoginModal();
                    return;
                }
                sendMessage();
            }
        });

        messageInput.addEventListener('input', () => {
            if (isWaiting) {
                updateStatus('请等待上一条消息处理完成', true);
            }
        });

        window.onload = () => {
            messageInput.focus();
        };

        // 点击模态框外部时关闭
        window.onclick = function(event) {
            if (event.target == loginModal) {
                closeLoginModal();
            }
        }

        function toggleDropdown() {
            const dropdown = document.querySelector('.dropdown-menu');
            dropdown.classList.toggle('show');
        }

        // 点击页面其他地方关闭下拉菜单
        document.addEventListener('click', function(event) {
            const dropdown = document.querySelector('.dropdown-menu');
            const avatar = document.querySelector('.user-avatar');
            if (!avatar.contains(event.target) && !dropdown.contains(event.target)) {
                dropdown.classList.remove('show');
            }
        });
        /*]]>*/
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html> 